package net.sppan.blog.controller.offer;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.log.Log;
import com.jfinal.plugin.redis.Redis;
import net.sppan.blog.bean.OfferRequestBean;
import net.sppan.blog.bean.OfferResponseBean;
import net.sppan.blog.bean.OfferResult;
import net.sppan.blog.controller.BaseController;
import net.sppan.blog.model.Offer;
import net.sppan.blog.store.ConfigStore;
import net.sppan.blog.store.OfferStore;
import net.sppan.blog.store.UserStore;
import net.sppan.blog.store.UserVerificationCache;
import net.sppan.blog.utils.AESUtil;
import net.sppan.blog.utils.ObjectUtils;
import net.sppan.blog.utils.OfferType;
import net.sppan.blog.utils.TransactionIdUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class OfferController extends BaseController {

	private static final Log log = Log.getLog("OfferController");

	private static final Log log1 = Log.getLog(OfferController.class);

	public void index() {
		OfferRequestBean requestBean = new OfferRequestBean();
		try {
			requestBean = getRequestObject(OfferRequestBean.class);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		String tid = TransactionIdUtil.compressedUUID();
		requestBean.setTid(tid);
		OfferResult bean = new OfferResult();
		try {
			//判断用户是否需要重新登录
			if (UserVerificationCache.get(requestBean.getUserID()) == null) {
				bean.setNeedLogin(true);
				renderText(AESUtil.encrypt(JSONObject.toJSONString(bean)));
				return;
			} else {
				if (!requestBean.getHardwareID().equals(UserVerificationCache.get(requestBean.getUserID()).getHardware())) {
					renderText("");
					return;
				}
				//先找到子账号的上级代理,因为offer是指派给代理的
				String parentId = UserStore.instance.getParentId(requestBean.getUserID());
				List<Offer> offers = OfferStore.getInstance().getOffers(parentId);
				if (offers == null) {
					offers = new ArrayList<>();
				}
				//有些offer可以投放所有用户
				List<Offer> superOffers = OfferStore.getInstance().getOffers("all");
				if (ObjectUtils.isNotEmpty(superOffers)) {
					offers.addAll(superOffers);
				}
				//排除点击数量受限的offer
				if (ObjectUtils.isNotEmpty(offers)) {
					Iterator<Offer> it = offers.iterator();
					while (it.hasNext()) {
						Offer o = it.next();
						if (limitClick(requestBean.getUserID(), parentId, o.getId().toString())) {
							it.remove();
						}
					}
				}

				if (ObjectUtils.isNotEmpty(offers)) {
					int size = offers.size();
					Collections.shuffle(offers);
					int count = requestBean.getCount();
					if (count > size) {
						count = size;
					}
					List<OfferResponseBean> beans = new ArrayList<>();
					for (int i = 0; i < count; i++) {
						Offer o = offers.get(i);
						OfferResponseBean ob = new OfferResponseBean();
						ob.setAdType(OfferType.getCode(o.getOfferType()));
						String domainName = ConfigStore.instance.getConfig().getDomainName();
						if (!domainName.endsWith("/")) {
							domainName += "/";
						}
						ob.setClickUrl(domainName + "click?" + buildClickUrl(requestBean, o));
						ob.setImpUrl("");
						ob.setShowRes("");
						ob.setShowType(1);
						ob.setOfferId(o.getId().toString());
						beans.add(ob);
					}
					bean.setNeedLogin(false);
					bean.setOffers(beans);
					renderText(AESUtil.encrypt(JSONObject.toJSONString(bean)));
					return;
				}
			}
		} catch (Exception e) {
			log1.error("", e);
		} finally {
			printLog(requestBean, bean);

		}

	}

	private boolean limitClick(String userId, String parentId, String offerId) {
		Integer userClick = Redis.use().get("user_" + userId) == null ? 0 : Redis.use().get("user_" + userId);
		Integer offerClick = Redis.use().get("offer_" + offerId) == null ? 0 : Redis.use().get("offer_" + offerId);
		Integer limit = UserStore.instance.getUserThreshold(parentId);
		Integer offerLimit = OfferStore.getInstance().getOfferById(offerId).getClickNumLimit();
		if(offerLimit == null){
			offerLimit = Integer.MAX_VALUE;
		}

		if (limit < userClick || offerLimit < offerClick) {
			return true;
		}
		return false;
	}

	private void printLog(OfferRequestBean requestBean, OfferResult bean) {
		StringBuilder requestSb = new StringBuilder();
		requestSb.append("aid=").append(requestBean.getAid()).append("&hardwareID=").append(requestBean.getHardwareID()).append("&userID=").append(requestBean.getUserID()).append("&count=").append(requestBean.getCount()).append("&network=").append(requestBean.getNetwork());
		StringBuilder response = new StringBuilder();
		String responseCode = "204";
		List<String> offerids = new ArrayList<>();
		if (ObjectUtils.isNotEmpty(bean.getOffers())) {
			responseCode = "200";
			for (OfferResponseBean ob : bean.getOffers()) {
				String offerId = ob.getOfferId();
				offerids.add(offerId);
			}
		}
		response.append("needLogin=").append(bean.isNeedLogin()).append("&responseCode=").append(responseCode).append("&offerIds=").append(ObjectUtils.listToString(offerids));
		//String time = SimpleDateFormatUtil.format(new Date(), SimpleDateFormatUtil.ymdhms);
		String logStr = String.format("%s\t%s\t%s\t%s", System.currentTimeMillis(), requestBean.getTid(), requestSb.toString(), response.toString());
		log.debug(logStr);
	}

	/**
	 * 手动触发reload offer
	 */
	public void reload() {
		OfferStore.getInstance().init();
		renderJson(true, "reload success");

	}

}
